package com.googlecode.quillen.util;

import java.util.WeakHashMap;
import java.util.Map;
import java.lang.ref.WeakReference;

/**
 * Created by IntelliJ IDEA.
 * User: greg
 * Date: Jan 10, 2009
 * Time: 2:21:12 PM
 *
 * Adapted from http://illegalargumentexception.blogspot.com/2008/04/java-synchronizing-on-transient-id.html
 */
public class MutexProvider
{
    private final Map<Mutex, WeakReference<Mutex>> mutexMap = new WeakHashMap<Mutex, WeakReference<Mutex>>();

    public Mutex getMutex(String id)
    {
        if (id == null)
        {
            throw new NullPointerException();
        }

        Mutex key = new Mutex(id);

        synchronized (mutexMap)
        {
            WeakReference<Mutex> ref = mutexMap.get(key);

            if (ref == null)
            {
                mutexMap.put(key, new WeakReference<Mutex>(key));
                return key;
            }

            Mutex mutex = ref.get();

            if (mutex == null)
            {
                mutexMap.put(key, new WeakReference<Mutex>(key));
                return key;
            }

            return mutex;
        }
    }

    public static class Mutex
    {
        private final String id;

        protected Mutex(String id)
        {
            this.id = id;
        }

        public boolean equals(Object o)
        {
            return o != null && this.getClass() == o.getClass() && this.id.equals(o.toString());
        }

        public int hashCode()
        {
            return id.hashCode();
        }

        public String toString()
        {
            return id;
        }
    }
}